use arm_linux_boot::ArmLinuxBoot;
use tracelog::log_faltal;

use super::{
    internal::{ALL_CPU_MASK, REV_11MPCORE},
    GICv2IrqState, GICv2StateInner,
};
use crate::GICv2State;

// 可能中断的最大数量, 由 GIC 体系架构决定
pub(crate) const GIC_MAXIRQ: usize = 1020;
// 起始的 32 个是针对每个 cpu 私有的(SGIs 和 PPIs)
pub(crate) const GIC_INTERNAL: usize = 32;
pub(crate) const GIC_NR_SGIS: usize = 16;
// 可能的 CPU 接口的最大数量, 由 GIC 体系架构决定
pub(crate) const GIC_NCPU: usize = 8;
// 各自 vCPU 的可能CPU接口的最大数量
pub(crate) const GIC_NCPU_VCPU: usize = GIC_NCPU * 2;

pub(crate) const MAX_NR_GROUP_PRIO: usize = 128;
pub(crate) const GIC_NR_APRS: usize = MAX_NR_GROUP_PRIO / 32;

pub(crate) const GIC_MIN_BPR: usize = 0;
pub(crate) const GIC_MIN_ABPR: usize = GIC_MIN_BPR + 1;

// 虚拟接口中列表寄存器的体系架构最大数目
pub(crate) const GIC_MAX_LR: usize = 64;

// vCPU 接口只能有 32 个优先级和 32 个抢占级
pub(crate) const GIC_VIRT_MAX_GROUP_PRIO_BITS: usize = 5;
pub(crate) const GIC_VIRT_MAX_NR_GROUP_PRIO: usize = 1 << GIC_VIRT_MAX_GROUP_PRIO_BITS;
pub(crate) const GIC_VIRT_NR_APRS: usize = GIC_VIRT_MAX_NR_GROUP_PRIO / 32;

pub(crate) const GIC_VIRT_MIN_BPR: usize = 2;
pub(crate) const GIC_VIRT_MIN_ABPR: usize = GIC_VIRT_MIN_BPR + 1;

// Number of SGI target-list bits
pub(crate) const GIC_TARGETLIST_BITS: usize = 8;
pub(crate) const GIC_MAX_PRIORITY_BITS: usize = 8;
pub(crate) const GIC_MIN_PRIORITY_BITS: usize = 4;

impl GICv2StateInner {
    pub(crate) fn arm_gic_common_realize(&mut self) {
        let num_irq = self.num_irq;

        if self.num_cpu > GIC_NCPU as u32 {
            log_faltal!("requested {} CPUs exceeds GIC maximum {}", self.num_cpu, GIC_NCPU);
            return;
        }
        if num_irq > GIC_MAXIRQ as u32 {
            log_faltal!("requested {} interrupt lines exceeds GIC maximum {}", num_irq, GIC_MAXIRQ);
            return;
        }
        // ITLinesNumber 表示为(N / 32) - 1(参见 gic_dist_readb), 所以这是一个实现强加的限制, 而不是架构上的限制
        if num_irq < 32 || num_irq % 32 != 0 {
            log_faltal!("{} interrupt lines unsupported: not divisible by 32", num_irq);
            return;
        }

        if self.security_extn && self.revision == REV_11MPCORE as u32 {
            log_faltal!("this GIC revision does not implement the security extensions");
            return;
        }

        if self.virt_extn {
            if self.revision != 2 {
                log_faltal!("GIC virtualization extensions are only supported by revision 2");
                return;
            }

            // 对于现在, 将实现的 LRs 的数量设置为 4, 就像大多数真实的 GICv2 一样. 如果需要用另一个 num_lrs 模拟一个变体,
            // 则可以将其提升为属性配置.
            self.num_lrs = 4;
        }
    }

    pub(crate) fn arm_gic_common_reset_irq_state(&mut self, first_cpu: usize, resetprio: i32) {
        for i in first_cpu..self.num_cpu as usize {
            if self.revision == REV_11MPCORE as u32 {
                self.priority_mask[i] = 0xf0;
            } else {
                self.priority_mask[i] = resetprio as u16;
            }
            self.current_pending[i] = 1023;
            self.running_priority[i] = 0x100;
            self.cpu_ctlr[i] = 0;
            self.bpr[i] =
                if self.gic_is_vcpu(i) { GIC_VIRT_MIN_BPR as u8 } else { GIC_MIN_BPR as u8 };
            self.abpr[i] =
                if self.gic_is_vcpu(i) { GIC_VIRT_MIN_ABPR as u8 } else { GIC_MIN_ABPR as u8 };

            if !self.gic_is_vcpu(i) {
                for j in 0..GIC_INTERNAL {
                    self.priority1[j][i] = resetprio as u8;
                }
                for j in 0..GIC_NR_SGIS {
                    self.sgi_pending[j][i] = 0;
                }
            }
        }
    }

    pub(crate) fn arm_gic_common_reset_hold(&mut self) {
        // 如果重置一个具有 TZ-aware 的 GIC, 就好像安全固件已经将其设置为准备在非安全中启动内核一样,
        // 我们需要将中断优先级设置为 `NS视图的零` 值. 这对于 `priority_mask[]` 值尤其重要,
        // 因为如果它们为 0, 那么 NS 代码就无法将优先级重写为其他任何东西.
        let resetprio = if self.security_extn && self.irq_reset_nonsecure { 0x80 } else { 0x0 };
        for this in self.irq_state.iter_mut() {
            *this = GICv2IrqState::default();
        }
        self.arm_gic_common_reset_irq_state(0, resetprio);

        if self.virt_extn {
            // vCPU 状态被存储在 GIC_NCPU.. GIC_NCPU+num_cpu.
            // 暴露的 vCPU 接口没有安全拓展.
            self.arm_gic_common_reset_irq_state(GIC_NCPU, 0);
        }

        for i in 0..GIC_NR_SGIS {
            self.gic_dist_set_enabled(i, ALL_CPU_MASK as u8);
            self.gic_dist_set_edge_trigger(i);
        }

        for this in self.priority2.iter_mut() {
            *this = resetprio as u8;
        }

        for i in 0..GIC_MAXIRQ {
            // 对于单处理器 IC, 所有中断总是针对唯一的 CPU
            if self.num_cpu == 1 {
                self.irq_target[i] = 1;
            } else {
                self.irq_target[i] = 0;
            }
        }
        if self.security_extn && self.irq_reset_nonsecure {
            for i in 0..GIC_MAXIRQ {
                self.gic_dist_set_group(i, ALL_CPU_MASK as u8);
            }
        }

        if self.virt_extn {
            for i in 0..self.num_lrs as usize {
                for j in 0..self.num_cpu as usize {
                    self.h_lr[i][j] = 0;
                }
            }

            for i in 0..self.num_cpu as usize {
                self.h_hcr[i] = 0;
                self.h_misr[i] = 0;
            }
        }

        self.ctlr = 0;
    }
}
